home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / SMILEYC.PAK / SMILECTL.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  9KB  |  316 lines

  1. // SmileCtl.cpp : Implementation of the CSmileCtrl OLE control class.
  2.  
  3. #include "stdafx.h"
  4. #include "Smile.h"
  5. #include "SmileCtl.h"
  6. #include "SmilePpg.h"
  7.  
  8.  
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14.  
  15.  
  16. IMPLEMENT_DYNCREATE(CSmileCtrl, COleControl)
  17.  
  18.  
  19. /////////////////////////////////////////////////////////////////////////////
  20. // Message map
  21.  
  22. BEGIN_MESSAGE_MAP(CSmileCtrl, COleControl)
  23.     //{{AFX_MSG_MAP(CSmileCtrl)
  24.     ON_WM_LBUTTONDOWN()
  25.     //}}AFX_MSG_MAP
  26.     ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
  27. END_MESSAGE_MAP()
  28.  
  29.  
  30. /////////////////////////////////////////////////////////////////////////////
  31. // Dispatch map
  32.  
  33. BEGIN_DISPATCH_MAP(CSmileCtrl, COleControl)
  34.     //{{AFX_DISPATCH_MAP(CSmileCtrl)
  35.     DISP_PROPERTY_NOTIFY(CSmileCtrl, "Sad", m_bSad, OnSadChanged, VT_BOOL)
  36.     DISP_FUNCTION(CSmileCtrl, "Beep", Beep, VT_EMPTY, VTS_NONE)
  37.     DISP_FUNCTION(CSmileCtrl, "Wink", Wink, VT_EMPTY, VTS_BOOL)
  38.     DISP_STOCKPROP_BACKCOLOR()
  39.     DISP_STOCKPROP_FONT()
  40.     DISP_STOCKPROP_FORECOLOR()
  41.     DISP_STOCKPROP_CAPTION()
  42.     DISP_STOCKPROP_BORDERSTYLE()
  43.     //}}AFX_DISPATCH_MAP
  44.     DISP_FUNCTION_ID(CSmileCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
  45. END_DISPATCH_MAP()
  46.  
  47.  
  48. /////////////////////////////////////////////////////////////////////////////
  49. // Event map
  50.  
  51. BEGIN_EVENT_MAP(CSmileCtrl, COleControl)
  52.     //{{AFX_EVENT_MAP(CSmileCtrl)
  53.     EVENT_CUSTOM("Outside", FireOutside, VTS_NONE)
  54.     EVENT_CUSTOM("Inside", FireInside, VTS_XPOS_PIXELS  VTS_YPOS_PIXELS)
  55.     //}}AFX_EVENT_MAP
  56. END_EVENT_MAP()
  57.  
  58.  
  59. /////////////////////////////////////////////////////////////////////////////
  60. // Property pages
  61.  
  62. // TODO: Add more property pages as needed.  Remember to increase the count!
  63. BEGIN_PROPPAGEIDS(CSmileCtrl, 3)
  64.     PROPPAGEID(CSmilePropPage::guid)
  65.     PROPPAGEID(CLSID_CColorPropPage)
  66.     PROPPAGEID(CLSID_CFontPropPage)
  67. END_PROPPAGEIDS(CSmileCtrl)
  68.  
  69.  
  70. /////////////////////////////////////////////////////////////////////////////
  71. // Initialize class factory and guid
  72.  
  73. IMPLEMENT_OLECREATE_EX(CSmileCtrl, "SMILE.SmileCtrl.1",
  74.     0x175cb003, 0xbeed, 0x11ce, 0x96, 0x11, 0, 0xaa, 0, 0x4a, 0x75, 0xcf)
  75.  
  76.  
  77. /////////////////////////////////////////////////////////////////////////////
  78. // Type library ID and version
  79.  
  80. IMPLEMENT_OLETYPELIB(CSmileCtrl, _tlid, _wVerMajor, _wVerMinor)
  81.  
  82.  
  83. /////////////////////////////////////////////////////////////////////////////
  84. // Interface IDs
  85.  
  86. const IID BASED_CODE IID_DSmile =
  87.         { 0x175cb001, 0xbeed, 0x11ce, { 0x96, 0x11, 0, 0xaa, 0, 0x4a, 0x75, 0xcf } };
  88. const IID BASED_CODE IID_DSmileEvents =
  89.         { 0x175cb002, 0xbeed, 0x11ce, { 0x96, 0x11, 0, 0xaa, 0, 0x4a, 0x75, 0xcf } };
  90.  
  91.  
  92. /////////////////////////////////////////////////////////////////////////////
  93. // Control type information
  94.  
  95. static const DWORD BASED_CODE _dwSmileOleMisc =
  96.     OLEMISC_ACTIVATEWHENVISIBLE |
  97.     OLEMISC_SETCLIENTSITEFIRST |
  98.     OLEMISC_INSIDEOUT |
  99.     OLEMISC_CANTLINKINSIDE |
  100.     OLEMISC_RECOMPOSEONRESIZE;
  101.  
  102. IMPLEMENT_OLECTLTYPE(CSmileCtrl, IDS_Smile, _dwSmileOleMisc)
  103.  
  104.  
  105. /////////////////////////////////////////////////////////////////////////////
  106. // CSmileCtrl::CSmileCtrlFactory::UpdateRegistry -
  107. // Adds or removes system registry entries for CSmileCtrl
  108.  
  109. BOOL CSmileCtrl::CSmileCtrlFactory::UpdateRegistry(BOOL bRegister)
  110. {
  111.     if (bRegister)
  112.         return AfxOleRegisterControlClass(
  113.             AfxGetInstanceHandle(),
  114.             m_clsid,
  115.             m_lpszProgID,
  116.             IDS_Smile,
  117.             IDB_Smile,
  118.             FALSE,                      //  Not insertable
  119.             _dwSmileOleMisc,
  120.             _tlid,
  121.             _wVerMajor,
  122.             _wVerMinor);
  123.     else
  124.         return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
  125. }
  126.  
  127.  
  128. /////////////////////////////////////////////////////////////////////////////
  129. // CSmileCtrl::CSmileCtrl - Constructor
  130.  
  131. CSmileCtrl::CSmileCtrl()
  132. {
  133.     InitializeIIDs(&IID_DSmile, &IID_DSmileEvents);
  134.  
  135.     m_bWink = FALSE;
  136. }
  137.  
  138.  
  139. /////////////////////////////////////////////////////////////////////////////
  140. // CSmileCtrl::~CSmileCtrl - Destructor
  141.  
  142. CSmileCtrl::~CSmileCtrl()
  143. {
  144.     // TODO: Cleanup your control's instance data here.
  145. }
  146.  
  147.  
  148. /////////////////////////////////////////////////////////////////////////////
  149. // CSmileCtrl::OnDraw - Drawing function
  150.  
  151. #define X(x) (int)(xLeft + (x)*xScale/100)    // Scaling macros
  152. #define Y(y) (int)(yTop + (y)*yScale/100)    // so scale is 0 - 100
  153. #define CX(x) (int)((x)*xScale/100)
  154. #define CY(y) (int)((y)*yScale/100)
  155.  
  156. void CSmileCtrl::OnDraw(
  157.             CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
  158. {
  159.     long xLeft = rcBounds.left;            // Use with scaling macros
  160.     long yTop = rcBounds.top;    
  161.     long xScale = rcBounds.Width();
  162.     long yScale = rcBounds.Height();    
  163.  
  164.     int iPenWidth = max(CX(5), CY(5)); // Pen width based on control size
  165.     CBrush brushBack;                   // Background brush
  166.     CBrush brushBlack;
  167.     CBrush brushYellow;
  168.     CPen penBlack(PS_SOLID, iPenWidth, RGB(0x00,0x00,0x00));
  169.     CPen penNull(PS_NULL, 0, (COLORREF)0);    // Null pen for drawing filled ellipses
  170.     COLORREF crBack = TranslateColor(GetBackColor());    //Use BackColor
  171.     brushBack.CreateSolidBrush(crBack);                 //Stock Property
  172.     brushBlack.CreateSolidBrush(RGB(0x00,0x00,0x00));
  173.     brushYellow.CreateSolidBrush(RGB(0xff,0xff,0x00));
  174.  
  175.     pdc->FillRect(rcBounds, &brushBack);                // Clear background
  176.  
  177.     CPen* pPenSave = pdc->SelectObject(&penBlack);
  178.     CBrush* pBrushSave = pdc->SelectObject(&brushYellow);
  179.     pdc->Ellipse(X(10), Y(15), X(90), Y(95));            // Head
  180.  
  181.     if (m_bSad)                                            // Use Sad
  182.     {                                                    // Custom Property
  183.         pdc->Arc(X(25), Y(70), X(75), Y(140),            // Sad Mouth
  184.                X(65), Y(75), X(35), Y(75));
  185.     } 
  186.     else 
  187.     {
  188.         pdc->Arc(X(25), Y(10), X(75), Y(80),            // Smile mouth
  189.                X(35), Y(70), X(65), Y(70));
  190.     }
  191.  
  192.  
  193.     pdc->SelectObject(&penNull);                        // No draw width
  194.     pdc->SelectObject(&brushBlack);
  195.  
  196.     if (m_bWink)                                        // Left Eye
  197.     {
  198.         iPenWidth = max(CX(1), CY(1));
  199.         CPen penThin(PS_SOLID, iPenWidth, RGB(0x00,0x00,0x00));
  200.         CPen* pThick = pdc->SelectObject(&penThin);
  201.  
  202.         pdc->MoveTo(X(57), Y(35));
  203.         pdc->LineTo(X(65), Y(50));
  204.         pdc->MoveTo(X(57), Y(50));
  205.         pdc->LineTo(X(65), Y(35));
  206.         pdc->SelectObject(pThick);
  207.     }
  208.     else
  209.     {
  210.         pdc->Ellipse(X(57), Y(35), X(65), Y(50));
  211.     }
  212.  
  213.     pdc->Ellipse(X(35), Y(35), X(43), Y(50));            // Right eye
  214.     pdc->Ellipse(X(46), Y(43), X(54), Y(58));            // Nose
  215.     
  216.     pdc->SetBkMode(TRANSPARENT);                        // Use ForeColor
  217.     pdc->SetTextColor(TranslateColor(GetForeColor()));    // Stock Property
  218.  
  219.     SelectStockFont(pdc);                                // Use Font 
  220.                                                         // Stock Property
  221.     CRect rect = rcBounds; 
  222.     pdc->DrawText(InternalGetText(), -1, rect,            // Use Caption 
  223.         DT_SINGLELINE | DT_CENTER | DT_TOP);            // Stock Propery
  224.  
  225.     pdc->SelectObject(pBrushSave);
  226.     pdc->SelectObject(pPenSave);
  227. }
  228.  
  229.  
  230. /////////////////////////////////////////////////////////////////////////////
  231. // CSmileCtrl::DoPropExchange - Persistence support
  232.  
  233. void CSmileCtrl::DoPropExchange(CPropExchange* pPX)
  234. {
  235.     ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  236.     COleControl::DoPropExchange(pPX);
  237.  
  238.     PX_Bool(pPX, _T("Sad"), m_bSad, FALSE);
  239.  
  240. }
  241.  
  242.  
  243. /////////////////////////////////////////////////////////////////////////////
  244. // CSmileCtrl::OnResetState - Reset control to default state
  245.  
  246. void CSmileCtrl::OnResetState()
  247. {
  248.     COleControl::OnResetState();  // Resets defaults found in DoPropExchange
  249.  
  250.     // TODO: Reset any other control state here.
  251. }
  252.  
  253.  
  254. /////////////////////////////////////////////////////////////////////////////
  255. // CSmileCtrl::AboutBox - Display an "About" box to the user
  256.  
  257. void CSmileCtrl::AboutBox()
  258. {
  259.     CDialog dlgAbout(IDD_ABOUTBOX_Smile);
  260.     dlgAbout.DoModal();
  261. }
  262.  
  263.  
  264. /////////////////////////////////////////////////////////////////////////////
  265. // CSmileCtrl message handlers
  266.  
  267. void CSmileCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
  268. {
  269.     CRect rcBounds;
  270.     GetClientRect(&rcBounds);
  271.  
  272.     long xLeft = rcBounds.left;    //Required by X() and Y() macros
  273.     long yTop = rcBounds.top;    
  274.     long xScale = rcBounds.Width();
  275.     long yScale = rcBounds.Height();
  276.  
  277.     if (InEllipse(point, X(10), Y(15), X(90), Y(95)))
  278.         FireInside((short)point.x, (short)point.y);
  279.     else
  280.         FireOutside();
  281.     
  282.     COleControl::OnLButtonDown(nFlags, point);
  283. }
  284.  
  285. //Simple Ellipse Hit-Testing
  286. BOOL CSmileCtrl::InEllipse(const CPoint& pt,
  287.     int x1, int y1, int x2, int y2)
  288. {
  289.     // Determine radii                       
  290.     double a = (x2 - x1) / 2;
  291.     double b = (y2 - y1) / 2;
  292.     
  293.     // Determine x, y
  294.     double x = pt.x - (x1 + x2) / 2;
  295.     double y = pt.y - (y1 + y2) / 2;
  296.     
  297.     // Apply ellipse formula
  298.     return ((x * x) / (a * a) + (y * y) / (b * b) <= 1);
  299. }
  300.  
  301. void CSmileCtrl::OnSadChanged() 
  302. {
  303.     InvalidateControl();
  304. }
  305.  
  306. void CSmileCtrl::Beep() 
  307. {
  308.     MessageBeep(0);
  309. }
  310.  
  311. void CSmileCtrl::Wink(BOOL bWink) 
  312. {
  313.     m_bWink = bWink;
  314.     InvalidateControl();
  315. }
  316.